#include "inetworking.h"
#include <QDataStream>
#include <QByteArray>
#include <QDataStream>
#include <QTcpSocket>
#include <QtEndian>

//*************************************************************
//IMPORTANT: if you are using the QT's way to communicate among internet
// please open this macro. else, commit it.
//*************************************************************
#define QT_MOCK_SERVER


INetWorking::INetWorking(QObject *parent) :
    QObject(parent)
{
    nextBlockSize = 0;
}

INetWorking::~INetWorking()
{
}

void INetWorking::setData(void* param, QByteArray *block)
{
    // invoke the corresponding class' prepareData
    // it is the responsibility of the owner class to check the paramer
    prepareWriteData(block, param);
}

bool INetWorking::recieveData(int bytesAvailable, QTcpSocket *pSocket)
{
    QDataStream in(pSocket);

    in.setVersion(QDataStream::Qt_4_3);

    bool bReady = false;
    protocal::BasePtc basePtc;

    // use dead loop is to simulate goto
    for(;;)
    {
        if (nextBlockSize == 0)
        {
            if( bytesAvailable < (int)sizeof(protocal::BasePtc) )
            {
                bReady = false;
                break;
            }

            // first catch the head of the protocal
            qint32 source, cli_command, size;
            in >> source >> cli_command >> size;
            basePtc.source = (protocal::SOURCE)source;
            basePtc.cli_command = (protocal::CLICOMMAND)cli_command;
#ifndef QT_MOCK_SERVER
            basePtc.size = qFromBigEndian(size);
#else
            basePtc.size = size;
#endif
            // nextBlockSize is the length of specific protocal's body
            nextBlockSize = basePtc.size - sizeof(protocal::BasePtc);
        }

        // in case the body of the protocal does not arrive together
        if (bytesAvailable < nextBlockSize)
        {
            bReady = false;
            break;
        }

        // read body data
        bReady = true;

        // clear the former resultMap
        resultMap.clear();

        if ( !prepareReadData(pSocket, &basePtc) )
        {
            qDebug() << "receive the data that is not we want\n";
            emit SendAndRecieveDifferentError();
        }

        // parepare for the next round
        nextBlockSize = 0;

        break;
    }

    return bReady;
}

// when we do not recieve any data, we return an empty QMap
QMap<QString, QString>* INetWorking::getResult()
{
   return &resultMap;
}

// when we do not recieve any data under this name, we return an empty QString
QString INetWorking::getResult(QString name)
{
    return resultMap.value(name);
}

